#include "grflib_stdafx.h"
#include "../include/BoxMesh.h"
#include "../include/VertexFormat.h"
#include "../include/D3D10Engine.h"

using namespace grflib::engine::core;
using namespace grflib::engine::aux;
using namespace grflib::engine;

const UINT CWireBox::m_nVertex = 8;
const UINT CWireBox::m_nIndex = 12 * 2;

static float faVertex[] = 
{
	//back
	0.0f, 0.0f, 0.0f,
	1.0f, 0.0f, 0.0f,
	1.0f, 1.0f, 0.0f,
	0.0f, 1.0f, 0.0f,
	//front
	0.0f, 0.0f, 1.0f,
	1.0f, 0.0f, 1.0f,
	1.0f, 1.0f, 1.0f,
	0.0f, 1.0f, 1.0f
};

static UINT faIndex[] = 
{
	//back
	0, 1,
	1, 2,
	2, 3,
	3, 0,
	//front
	4, 5,
	5, 6,
	6, 7,
	7, 4,
	//left & right
	0, 4,
	1, 5,
	2, 6,
	3, 7
};

CWireBox::CWireBox(float scaleX, float scaleY, float scaleZ)
    : m_sx(scaleX),
    m_sy(scaleY),
    m_sz(scaleZ)
{
	m_bbox.Cube(0.0f);
	CreateMesh();
	m_nGroups = 1;
}

CWireBox::~CWireBox()
{
	OnDestroy();
}

BBox<float> &CWireBox::GetBoundingBox()
{
	return m_bbox;
}

void CWireBox::CreateMesh()
{
	boost::shared_ptr< std::vector<float> > pVertices;
	boost::shared_ptr< std::vector<DWORD> > pIndices;

	boost::shared_ptr<std::vector<D3D10_INPUT_ELEMENT_DESC>> pElements;
	std::size_t stride;

    pVertices.reset( new std::vector<float> );
    pIndices.reset( new std::vector<DWORD> );
    pElements.reset( new std::vector<D3D10_INPUT_ELEMENT_DESC> );
    vertex_format::Mapping(*pElements, stride);

    for (UINT i = 0; i < m_nVertex * 3; i += 3)
    {
        pVertices->push_back(faVertex[i] * m_sx);
        pVertices->push_back(faVertex[i + 1] * m_sy);
        pVertices->push_back(faVertex[i + 2] * m_sz);
    }

    for (UINT i = 0; i < m_nIndex; i++)
        pIndices->push_back(faIndex[i]);

    m_vertexVec.push_back(pVertices);
    m_indexVec.push_back(pIndices);
    m_primitiveTopology.push_back(D3D10_PRIMITIVE_TOPOLOGY_LINELIST);
    m_vertexLayouts.push_back(pElements);
    m_vertexStride.push_back(stride);
}

bool CWireBox::SetScale(float scaleX, float scaleY, float scaleZ)
{
    m_sx = scaleX;
    m_sy = scaleY;
    m_sz = scaleZ;

    if (m_vertexVec.size() <= 0 || m_vertexVec[0]->size() < m_nVertex * 3)
        return false;

    boost::shared_ptr< std::vector<float> > pVertices = m_vertexVec[0];
    for (size_t i = 0; i < m_nVertex * 3; i += 3)
    {
        (*pVertices)[i] = faVertex[i] * m_sx;
        (*pVertices)[i + 1] = faVertex[i + 1] * m_sy;
        (*pVertices)[i + 2] = faVertex[i + 2] * m_sz;
    }

    CEngine::Instance().GetD3DDevice()->UpdateSubresource(m_vertexBufferPtrs[0], 0, 0, &(*m_vertexVec[0])[0], 0, 0);
    return true;
}

void CWireBox::SetMaterial(const std::string &materialName)
{
    m_materials[0] = materialName;
}
